﻿@{
    Layout = "~/Views/Shared/_Layout_Turorials.cshtml";
}
<h1>Grain Persistence </h1>

<h2 id="grain-persistence-goals">Grain Persistence Goals</h2>

<ol>
    <li>Allow different grain types to use different types of storage providers (e.g., one uses Azure table, and one uses SQL Azure) or the same type of storage provider but with different configurations (e.g., both use Azure table, but one uses storage account #1 and one uses storage account #2)</li>
    <li>Allow configuration of a storage provider instance to be swapped (e.g., Dev-Test-Prod) with just config file changes, and no code changes required.</li>
    <li>Provide a framework to allow additional storage providers to be written later, either by the Orleans team or others.</li>
    <li>Provide a minimal set of production-grade storage providers</li>
    <li>Storage providers have complete control over how they store grain state data in persistent backing store. Corollary: Orleans is not providing a comprehensive ORM storage solution, but allows custom storage providers to support specific ORM requirements as and when required.</li>
</ol>

<h2 id="grain-persistence-api">Grain Persistence API</h2>

<p>Grain types can be declared in one of two ways:</p>

<ul>
    <li>Extend <code class="highlighter-rouge">Grain</code> if they do not have any persistent state, or if they will handle all persistent state themselves, or</li>
    <li>
        Extend <code class="highlighter-rouge">Grain&lt;T&gt;</code> if they have some persistent state that they want the Orleans runtime to handle.
        Stated another way, by extending <code class="highlighter-rouge">Grain&lt;T&gt;</code> a grain type is automatically opted-in to the Orleans system managed persistence framework.
    </li>
</ul>

<p>For the remainder of this section, we will only be considering Option #2 / <code class="highlighter-rouge">Grain&lt;T&gt;</code> because Option #1 grains will continue to run as now without any behavior changes.</p>

<h2 id="grain-state-stores">Grain State Stores</h2>

<p>Grain classes that inherit from <code class="highlighter-rouge">Grain&lt;T&gt;</code> (where <code class="highlighter-rouge">T</code> is an application-specific state data type derived from <code class="highlighter-rouge">GrainState</code>) will have their state loaded automatically from a specified storage.</p>

<p>Grains will be marked with a <code class="highlighter-rouge">[StorageProvider]</code> attribute that specifies a named instance of a storage provider to use for reading / writing the state data for this grain.</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="na">[StorageProvider(ProviderName="store1")]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">MyGrain</span><span class="p">&lt;</span><span class="n">MyGrainState</span><span class="p">&gt;</span> <span class="p">...</span>
<span class="p">{</span>
    <span class="p">...</span>
<span class="p">}</span>
</code></pre>
</div>

<p>The Orleans Provider Manager framework provides a mechanism to specify &amp; register different storage providers and storage options in the silo config file.</p>

<div class="language-xml highlighter-rouge">
    <pre class="highlight"><code><span class="nt">&lt;OrleansConfiguration</span> <span class="na">xmlns=</span><span class="s">"urn:orleans"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;Globals&gt;</span>
    <span class="nt">&lt;StorageProviders&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.MemoryStorage"</span> <span class="na">Name=</span><span class="s">"DevStore"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.AzureTableStorage"</span> <span class="na">Name=</span><span class="s">"store1"</span>
    <span class="na">DataConnectionString=</span><span class="s">"DefaultEndpointsProtocol=https;AccountName=data1;AccountKey=SOMETHING1"</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.AzureBlobStorage"</span> <span class="na">Name=</span><span class="s">"store2"</span>
    <span class="na">DataConnectionString=</span><span class="s">"DefaultEndpointsProtocol=https;AccountName=data2;AccountKey=SOMETHING2"</span>  <span class="nt">/&gt;</span>
    <span class="nt">&lt;/StorageProviders&gt;</span>
</code></pre>
</div>

<h2 id="configuring-storage-providers">Configuring Storage Providers</h2>

<h3 id="azuretablestorage">AzureTableStorage</h3>

<div class="language-xml highlighter-rouge">
    <pre class="highlight"><code><span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.AzureTableStorage"</span> <span class="na">Name=</span><span class="s">"TableStore"</span>
    <span class="na">DataConnectionString=</span><span class="s">"UseDevelopmentStorage=true"</span> <span class="nt">/&gt;</span>
</code></pre>
</div>

<p>The following attributes can be added to the <code class="highlighter-rouge">&lt;Provider /&gt;</code> element to configure the provider:</p>

<ul>
    <li><strong><code class="highlighter-rouge">DataConnectionString="..."</code></strong> (mandatory) - The Azure storage connection string to use</li>
    <li><strong><code class="highlighter-rouge">TableName="OrleansGrainState"</code></strong> (optional) - The table name to use in table storage, defaults to <code class="highlighter-rouge">OrleansGrainState</code></li>
    <li><strong><code class="highlighter-rouge">DeleteStateOnClear="false"</code></strong> (optional) - If true, the record will be deleted when grain state is cleared, otherwise an null record will be written, defaults to <code class="highlighter-rouge">false</code></li>
    <li><strong><code class="highlighter-rouge">UseJsonFormat="false"</code></strong> (optional) - If true, the json serializer will be used, otherwise the Orleans binary serializer will be used, defaults to <code class="highlighter-rouge">false</code></li>
    <li><strong><code class="highlighter-rouge">UseFullAssemblyNames="false"</code></strong> (optional) - (if <code class="highlighter-rouge">UseJsonFormat="true"</code>) Serializes types with full assembly names (true) or simple (false), defaults to <code class="highlighter-rouge">false</code></li>
    <li><strong><code class="highlighter-rouge">IndentJSON="false"</code></strong> (optional) - (if <code class="highlighter-rouge">UseJsonFormat="true"</code>) Indents the serialized json, defaults to <code class="highlighter-rouge">false</code></li>
</ul>

<blockquote>
    <p><strong>Note:</strong> state should not exceed 64KB, a limit imposed by Table Storage.</p>
</blockquote>

<h3 id="azureblobstorage">AzureBlobStorage</h3>

<div class="language-xml highlighter-rouge">
    <pre class="highlight"><code><span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.AzureTableStorage"</span> <span class="na">Name=</span><span class="s">"BlobStore"</span>
    <span class="na">DataConnectionString=</span><span class="s">"UseDevelopmentStorage=true"</span> <span class="nt">/&gt;</span>
</code></pre>
</div>

<p>The following attributes can be added to the <code class="highlighter-rouge">&lt;Provider /&gt;</code> element to configure the provider:</p>

<ul>
    <li><strong><code class="highlighter-rouge">DataConnectionString="..."</code></strong> (mandatory) - The Azure storage connection string to use</li>
    <li><strong><code class="highlighter-rouge">ContainerName="grainstate"</code></strong> (optional) - The blob storage container to use, defaults to <code class="highlighter-rouge">grainstate</code></li>
    <li><strong><code class="highlighter-rouge">UseFullAssemblyNames="false"</code></strong> (optional) - Serializes types with full assembly names (true) or simple (false), defaults to <code class="highlighter-rouge">false</code></li>
    <li><strong><code class="highlighter-rouge">IndentJSON="false"</code></strong> (optional) - Indents the serialized json, defaults to <code class="highlighter-rouge">false</code></li>
</ul>

<!--
### SqlStorageProvider

```xml
<Provider Type="Orleans.SqlUtils.StorageProvider.SqlStorageProvider" Name="SqlStore"
    ConnectionString="..." />
```
* __`ConnectionString="..."`__ (mandatory) - The SQL connection string to use
* __`MapName=""`__ ???
* __`ShardCredentials=""`__ ???
* __`StateMapFactoryType=""`__ (optional) defaults to `Lazy`???
* __`Ignore="false"`__ (optional) - If true, disables persistence, defaults to `false`
-->

<h3 id="memorystorage">MemoryStorage</h3>

<div class="language-xml highlighter-rouge">
    <pre class="highlight"><code><span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.MemoryStorage"</span> <span class="na">Name=</span><span class="s">"MemoryStorage"</span>  <span class="nt">/&gt;</span>
</code></pre>
</div>
<blockquote>
    <p><strong>Note:</strong> This provider persists state to volatile memory which is erased at silo shut down. Use only for testing.</p>
</blockquote>

<ul>
    <li><strong><code class="highlighter-rouge">NumStorageGrains="10"</code></strong> (optional) - The number of grains to use to store the state, defaults to <code class="highlighter-rouge">10</code></li>
</ul>

<h3 id="shardedstorageprovider">ShardedStorageProvider</h3>

<div class="language-xml highlighter-rouge">
    <pre class="highlight"><code><span class="nt">&lt;Provider</span> <span class="na">Type=</span><span class="s">"Orleans.Storage.ShardedStorageProvider"</span> <span class="na">Name=</span><span class="s">"ShardedStorage"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;Provider</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/Provider&gt;</span>
</code></pre>
</div>
<p>Simple storage provider for writing grain state data shared across a number of other storage providers.</p>

<p>
    A consistent hash function (default is Jenkins Hash) is used to decide which
    shard (in the order they are defined in the config file) is responsible for storing
    state data for a specified grain, then the Read / Write / Clear request
    is bridged over to the appropriate underlying provider for execution.
</p>

<h2 id="notes-on-storage-providers">Notes on Storage Providers</h2>

<p>
    If there is no <code class="highlighter-rouge">[StorageProvider]</code> attribute specified for a <code class="highlighter-rouge">Grain&lt;T&gt;</code> grain class, then a provider named <code class="highlighter-rouge">Default</code> will be searched for instead.
    If not found then this is treated as a missing storage provider.
</p>

<p>If there is only one provider in the silo config file, it will be considered to be the <code class="highlighter-rouge">Default</code> provider for this silo.</p>

<p>
    A grain that uses a storage provider which is not present and defined in the silo configuration when the silo loads will fail to load, but the rest of the grains in that silo can still load and run.
    Any later calls to that grain type will fail with an <code class="highlighter-rouge">Orleans.Storage.BadProviderConfigException</code> error specifying that the grain type is not loaded.
</p>

<p>The storage provider instance to use for a given grain type is determined by the combination of the storage provider name defined in the <code class="highlighter-rouge">[StorageProvider]</code> attribute on that grain type, plus the provider type and configuration options for that provider defined in the silo config.</p>

<p>Different grain types can use different configured storage providers, even if both are the same type: for example, two different Azure table storage provider instances, connected to different Azure storage accounts (see config file example above).</p>

<p>
    All configuration details for storage providers is defined statically in the silo configuration that is read at silo startup.
    There are <em>no</em> mechanisms provided at this time to dynamically update or change the list of storage providers used by a silo.
    However, this is a prioritization / workload constraint rather than a fundamental design constraint.
</p>

<h2 id="state-storage-apis">State Storage APIs</h2>

<p>There are two main parts to the grain state / persistence APIs: Grain-to-Runtime and Runtime-to-Storage-Provider.</p>

<h2 id="grain-state-storage-api">Grain State Storage API</h2>

<p>
    The grain state storage functionality in the Orleans Runtime will provide read and write operations to automatically populate / save the <code class="highlighter-rouge">GrainState</code> data object for that grain.
    Under the covers, these functions will be connected (within the code generated by Orleans client-gen tool) through to the appropriate persistence provider configured for that grain.
</p>

<h2 id="grain-state-read--write-functions">Grain State Read / Write Functions</h2>

<p>
    Grain state will automatically be read when the grain is activated, but grains are responsible for explicitly triggering the write for any changed grain state as and when necessary.
    See the <a href="#FailureModes">Failure Modes</a> section below for details of error handling mechanisms.
</p>

<p>
    <code class="highlighter-rouge">GrainState</code> will be read automatically (using the equivalent of <code class="highlighter-rouge">base.ReadStateAsync()</code>) <em>before</em> the <code class="highlighter-rouge">OnActivateAsync()</code> method is called for that activation.
    <code class="highlighter-rouge">GrainState</code> will not be refreshed before any method calls to that grain, unless the grain was activated for this call.
</p>

<p>
    During any grain method call, a grain can request the Orleans runtime to write the current grain state data for that activation to the designated storage provider by calling <code class="highlighter-rouge">base.WriteStateAsync()</code>.
    The grain is responsible for explicitly performing write operations when they make significant updates to their state data.
    Most commonly, the grain method will return the <code class="highlighter-rouge">base.WriteStateAsync()</code> <code class="highlighter-rouge">Task</code> as the final result <code class="highlighter-rouge">Task</code> returned from that grain method, but it is not required to follow this pattern.
    The runtime will not automatically update stored grain state after any grain methods.
</p>

<p>
    During any grain method or timer callback handler in the grain, the grain can request the Orleans runtime to re-read the current grain state data for that activation from the designated storage provider by calling <code class="highlighter-rouge">base.ReadStateAsync()</code>.
    This will completely overwrite any current state data currently stored in the grain state object with the latest values read from persistent store.
</p>

<p>
    An opaque provider-specific <code class="highlighter-rouge">Etag</code> value (<code class="highlighter-rouge">string</code>) <em>may</em> be set by a storage provider as part of the grain state metadata populated when state was read.
    Some providers may choose to leave this as <code class="highlighter-rouge">null</code> if they do not use <code class="highlighter-rouge">Etag</code>s.
</p>

<p>Conceptually, the Orleans Runtime will take a deep copy of the grain state data object for its own use during any write operations. Under the covers, the runtime <em>may</em> use optimization rules and heuristics to avoid performing some or all of the deep copy in some circumstances, provided that the expected logical isolation semantics are preserved.</p>

<h2 id="sample-code-for-grain-state-read--write-operations">Sample Code for Grain State Read / Write Operations</h2>

<p>
    Grains must extend the <code class="highlighter-rouge">Grain&lt;T&gt;</code> class in order to participate in the Orleans grain state persistence mechanisms.
    The <code class="highlighter-rouge">T</code> in the above definition will be replaced by an application-specific grain state class for this grain; see the example below.
</p>

<p>The grain class should also be annotated with a <code class="highlighter-rouge">[StorageProvider]</code> attribute that tells the runtime which storage provider (instance) to use with grains of this type.</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="n">MyGrainState</span> <span class="p">:</span> <span class="n">GrainState</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">Field1</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">Field2</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="na">[StorageProvider(ProviderName="store1")]</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">MyPersistenceGrain</span> <span class="p">:</span> <span class="n">Grain</span><span class="p">&lt;</span><span class="n">MyGrainState</span><span class="p">&gt;,</span> <span class="n">IMyPersistenceGrain</span>
<span class="p">{</span>
    <span class="p">...</span>
<span class="p">}</span>
</code></pre>
</div>

<h2 id="grain-state-read">Grain State Read</h2>

<p>
    The initial read of the grain state will occur automatically by the Orleans runtime before the grain’s <code class="highlighter-rouge">OnActivateAsync()</code> method is called; no application code is required to make this happen.
    From that point forward, the grain’s state will be available through the <code class="highlighter-rouge">Grain&lt;T&gt;.State</code> property inside the grain class.
</p>

<h2 id="grain-state-write">Grain State Write</h2>

<p>
    After making any appropriate changes to the grain’s in-memory state, the grain should call the <code class="highlighter-rouge">base.WriteStateAsync()</code> method to write the changes to the persistent store via the defined storage provider for this grain type.
    This method is asynchronous and returns a <code class="highlighter-rouge">Task</code> that will typically be returned by the grain method as its own completion Task.
</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">public</span> <span class="n">Task</span> <span class="nf">DoWrite</span><span class="p">(</span><span class="kt">int</span> <span class="n">val</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">State</span><span class="p">.</span><span class="n">Field1</span> <span class="p">=</span> <span class="n">val</span><span class="p">;</span>
    <span class="k">return</span> <span class="k">base</span><span class="p">.</span><span class="nf">WriteStateAsync</span><span class="p">();</span>
<span class="p">}</span>
</code></pre>
</div>

<h2 id="grain-state-refresh">Grain State Refresh</h2>

<p>
    If a grain wishes to explicitly re-read the latest state for this grain from backing store, the grain should call the <code class="highlighter-rouge">base.ReadStateAsync()</code> method.
    This will reload the grain state from persistent store, via the defined storage provider for this grain type, and any previous in-memory copy of the grain state will be overwritten and replaced when the <code class="highlighter-rouge">ReadStateAsync()</code> <code class="highlighter-rouge">Task</code> completes.
</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">public</span> <span class="n">async</span> <span class="n">Task</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="nf">DoRead</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">await</span> <span class="k">base</span><span class="p">.</span><span class="nf">ReadStateAsync</span><span class="p">();</span>
    <span class="k">return</span> <span class="n">State</span><span class="p">.</span><span class="n">Field1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
</div>

<h2 id="failure-modes-for-grain-state-persistence-operations-a-namefailuremodesa">Failure Modes for Grain State Persistence Operations <a name="FailureModes"></a></h2>

<h3 id="failure-modes-for-grain-state-read-operations">Failure Modes for Grain State Read Operations</h3>

<p>
    Failures returned by the storage provider during the initial read of state data for that particular grain will result in the activate operation for that grain to be failed; in this case, there will <em>not</em> be any call to that grain’s <code class="highlighter-rouge">OnActivateAsync()</code> life cycle callback method.
    The original request to that grain which caused the activation will be faulted back to the caller the same way as any other failure during grain activation.
    Failures encountered by the storage provider to read state data for a particular grain will result in the <code class="highlighter-rouge">ReadStateAsync()</code> <code class="highlighter-rouge">Task</code> to be faulted.
    The grain can choose to handle or ignore that faulted <code class="highlighter-rouge">Task</code>, just like any other <code class="highlighter-rouge">Task</code> in Orleans.
</p>

<p>Any attempt to send a message to a grain which failed to load at silo startup time due to a missing / bad storage provider config will return the permanent error <code class="highlighter-rouge">Orleans.BadProviderConfigException</code>.</p>

<h3 id="failure-modes-for-grain-state-write-operations">Failure Modes for Grain State Write Operations</h3>

<p>
    Failures encountered by the storage provider to write state data for a particular grain will result in the <code class="highlighter-rouge">WriteStateAsync()</code> <code class="highlighter-rouge">Task</code> to be faulted.
    Usually, this will mean the grain call will be faulted back to the client caller provided the <code class="highlighter-rouge">WriteStateAsync()</code> <code class="highlighter-rouge">Task</code> is correctly chained in to the final return <code class="highlighter-rouge">Task</code> for this grain method.
    However, it will be possible for certain advanced scenarios to write grain code to specifically handle such write errors, just like they can handle any other faulted <code class="highlighter-rouge">Task</code>.
</p>

<p>Grains that execute error-handling / recovery code <em>must</em> catch exceptions / faulted <code class="highlighter-rouge">WriteStateAsync()</code> <code class="highlighter-rouge">Task</code>s and not re-throw to signify that they have successfully handled the write error.</p>

<h2 id="storage-provider-framework">Storage Provider Framework</h2>

<p>There is a service provider API for writing additional persistence providers – <code class="highlighter-rouge">IStorageProvider</code>.</p>

<p>The Persistence Provider API covers read and write operations for GrainState data.</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="n">IStorageProvider</span>
<span class="p">{</span>
    <span class="n">Logger</span> <span class="n">Log</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
    <span class="n">Task</span> <span class="nf">Init</span><span class="p">();</span>
    <span class="n">Task</span> <span class="nf">Close</span><span class="p">();</span>
    <span class="n">Task</span> <span class="nf">ReadStateAsync</span><span class="p">(</span><span class="kt">string</span> <span class="n">grainType</span><span class="p">,</span> <span class="n">GrainId</span> <span class="n">grainId</span><span class="p">,</span> <span class="n">GrainState</span> <span class="n">grainState</span><span class="p">);</span>
    <span class="n">Task</span> <span class="nf">WriteStateAsync</span><span class="p">(</span><span class="kt">string</span> <span class="n">grainType</span><span class="p">,</span> <span class="n">GrainId</span> <span class="n">grainId</span><span class="p">,</span> <span class="n">GrainState</span> <span class="n">grainState</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>

<h2 id="storage-provider-semantics">Storage Provider Semantics</h2>

<p>Any attempt to perform a write operation when the storage provider detects an <code class="highlighter-rouge">Etag</code> constraint violation <em>should</em> cause the write <code class="highlighter-rouge">Task</code> to be faulted with transient error <code class="highlighter-rouge">Orleans.InconsistentStateException</code> and wrapping the underlying storage exception.</p>

<div class="language-csharp highlighter-rouge">
    <pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">InconsistentStateException</span> <span class="p">:</span> <span class="n">AggregateException</span>
<span class="p">{</span>
    <span class="c1">/// &lt;summary&gt;The Etag value currently held in persistent storage.&lt;/summary&gt;
</span>  <span class="k">public</span> <span class="kt">string</span> <span class="n">StoredEtag</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
    <span class="c1">/// &lt;summary&gt;The Etag value currently held in memory, and attempting to be updated.&lt;/summary&gt;
</span>  <span class="k">public</span> <span class="kt">string</span> <span class="n">CurrentEtag</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">public</span> <span class="nf">InconsistentStateException</span><span class="p">(</span>
    <span class="kt">string</span> <span class="n">errorMsg</span><span class="p">,</span>
    <span class="kt">string</span> <span class="n">storedEtag</span><span class="p">,</span>
    <span class="kt">string</span> <span class="n">currentEtag</span><span class="p">,</span>
    <span class="n">Exception</span> <span class="n">storageException</span>
    <span class="p">)</span> <span class="p">:</span> <span class="k">base</span><span class="p">(</span><span class="n">errorMsg</span><span class="p">,</span> <span class="n">storageException</span><span class="p">)</span>
    <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="n">StoredEtag</span> <span class="p">=</span> <span class="n">storedEtag</span><span class="p">;</span>
    <span class="k">this</span><span class="p">.</span><span class="n">CurrentEtag</span> <span class="p">=</span> <span class="n">currentEtag</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">public</span> <span class="nf">InconsistentStateException</span><span class="p">(</span><span class="kt">string</span> <span class="n">storedEtag</span><span class="p">,</span> <span class="kt">string</span> <span class="n">currentEtag</span><span class="p">,</span> <span class="n">Exception</span> <span class="n">storageException</span><span class="p">)</span>
    <span class="p">:</span> <span class="k">this</span><span class="p">(</span><span class="n">storageException</span><span class="p">.</span><span class="n">Message</span><span class="p">,</span> <span class="n">storedEtag</span><span class="p">,</span> <span class="n">currentEtag</span><span class="p">,</span> <span class="n">storageException</span><span class="p">)</span>
    <span class="p">{</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<p>Any other failure conditions from a write operation <em>should</em> cause the write <code class="highlighter-rouge">Task</code> to be broken with an exception containing the underlying storage exception.</p>

<h2 id="data-mapping">Data Mapping</h2>

<p>Individual storage providers should decide how best to store grain state – blob (various formats / serialized forms) or column-per-field are obvious choices.</p>

<p>The basic storage provider for Azure Table encodes state data fields into a single table column using Orleans binary serialization.</p>
